<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // function Person(name,age){  
        //       this.name = name;
        //       this.age = age; 
        // }

        // Person.prototype.sayHello = function(){
        //     console.log('我是原型继承');
        // }

        // function Student(){
        //     //直接在子类中return一个父类的实例
        //     const p1 = new Person('张三',18);
        //     return p1;
        // }

        // const s1 = new Student();
        // console.log(s1);
        // console.log(s1.name);
        // console.log(s1.age);
        // s1.sayHello();


        // 看似是 student 的实例 但是实际上是 person 的实例


        // 需要改造一下 

        // 构造函数不能写return 
        // function Person(name,age){  
        //       this.name = name;
        //       this.age = age; 
        // }

        // Person.prototype.sayHello = function(){
        //     console.log('我是原型继承');
        // }


        // function Student(gender){
        //     this.gender = gender
        // }

        // Student.prototype = Person.prototype;
        // 直接将子类的原型指向父类的原型
        // 实现寄生  

        // const s1 = new Student('男');
        // console.log(s1);
        
        // s1.sayHello(); //方法可以继承过来
        // console.log(s1.name); // 属性不能继承过来
        // console.log(s1.age);


        // 继续改造 
        // function Person(name,age){  
        //       this.name = name;
        //       this.age = age; 
        // }

        // Person.prototype.sayHello = function(){
        //     console.log('我是原型继承');
        // }

        // // 借助于第三方 
        

        // function Third(){
        //     // 用来做中转   
        // }

        // Third.prototype = Person.prototype;

        // const t1 = new Third();
        // // console.log(t1);

        // function Student(...arg){
        //     Person.call(this,...arg);
        // }

        // Student.prototype = new Third();
        // //  指向了第三方的实例

        // const s1 = new Student('张三',18);
        // console.log(s1);
        // console.log(s1.name);
        // console.log(s1.age);
        // s1.sayHello();


        // 借助第三方的实例 可以拿到属性 
        // 不借助 只能拿到方法   
        // 但是这样的话 会多出一套属性



        // 如何让一个函数自动运行 


        // (function(){
        //     var a = 10;
        //     console.log(a);
        // })()
        //最终版
        function Person(name,age){  
              this.name = name;
              this.age = age; 
        }

        Person.prototype.sayHello = function(){
            console.log('我是原型继承');
        }

        const student = (function(){
            //创造一个子类构造函数
            function Student(gender,...arg){
                this.gender = gender;
                Person.call(this,...arg);
            }

            // 借助第三方
            function Third(){}
            Third.prototype = Person.prototype;
            Student.prototype = new Third();  
            Student.prototype.constructor = Student; 
            Student.prototype.sayGood = function(){
                console.log('我是子类的方法');
            }
            return Student;
        })()

        // console.log(student)



        const s1 = new student('男','张三',18);
        console.log(s1);


        // 拿到了父类的属性和方法
        s1.sayHello();



        // 构造函数 只能继承属性 不能继承方法
        // 
    </script>
</body>
</html>